
const g = require('../utils/global');

cc.Class({
    extends: cc.Component,

    properties: {
        planePrefab: {
            type: cc.Prefab,
            default: null,
        },
        enemyPrefab: {
            type: cc.Prefab,
            default: null,
        },
        // 飞机子弹
        heroBulletPrefab: {
            type: cc.Prefab,
            default: null,
        },
        // 上下两个背景
        topBackground: {
            type: cc.Sprite,
            default: null,
        },
        downBackground: {
            type: cc.Sprite,
            default: null,
        },
        // 爆炸效果
        bombPrefab: {
            type: cc.Prefab,
            default: null,
        },
        // 英雄血量
        blood: {
            type: cc.Sprite,
            default: null,
        }
    },

    // 设置控制器
    setController(controller) {
        this.controller = controller;
        // 所有飞机，0=英雄， 敌机
        this.planeViews = {};
        // // 英雄发出的子弹
        // this.heroBullets = [];
        // TODO support enemy bullet
        this.enemyBullets = [];
    },

    initPlaneModel(model) {
        // 添加节点
        const plane = cc.instantiate(this.planePrefab);
        // 挂在sky节点下
        this.node.addChild(plane);
        const planeView = plane.getComponent('planeView');
        planeView.initWithModel(model);
        planeView.setController(this.controller);
        this.planeViews[model.id] = planeView;
        this.plane = plane;
    },

    onLoad() {
        this.isClick = false;
        this.registerEvent();
        // update plane view
        this.updateView();
        // 开火
        this.planeFire();
        this.genNewEnemy();
        this.gameOver = false;
        // this.count = 0;
    },

    // 生成新的敌机
    genNewEnemy() {
        cc.log('create enemy');
        const delay = cc.delayTime(g.AnimTime.enemyCreated);
        // 循环生成敌机
        const createEnemy = cc.callFunc(function (node, sky) {
            if(sky.gameOver) {
                return;
            }
            const model = sky.controller.genNewEnemy();
            const enemy = cc.instantiate(sky.enemyPrefab);
            node.addChild(enemy);
            const enemyView = enemy.getComponent('enemyView');
            enemyView.initWithModel(model);
            enemyView.setController(sky.controller);
            sky.planeViews[model.id]  = enemyView;
            enemyView.moving();
            const delay = cc.delayTime(g.AnimTime.enemyCreated);
            node.runAction(cc.sequence(delay, createEnemy));
        }, this.node, this);
        this.node.runAction(cc.sequence(delay, createEnemy));
    },

    // 飞机开火
    planeFire() {
        cc.log('plane fire');
        // 动作循环开火
        const fire = cc.callFunc(function (node, sky) {
            if(sky.gameOver) {
                // 飞机死了
                return;
            }
            const bullet = cc.instantiate(sky.heroBulletPrefab);
            node.addChild(bullet);
            const bulletView = bullet.getComponent('bulletView');
            // 82为机头的偏移
            bulletView.fire(sky.planeViews[0].node.x, sky.planeViews[0].node.y+82, sky.controller, 1);
            const delay = cc.delayTime(g.AnimTime.heroBullet);
            node.runAction(cc.sequence(delay, fire));
        }, this.node, this);
        const delay = cc.delayTime(g.AnimTime.heroBullet);
        this.node.runAction(cc.sequence(delay, fire))
    },
    // 监听事件
    registerEvent() {
        this.node.on(cc.Node.EventType.TOUCH_START, function (eventTouch) {
            // 是否点击飞机
            const touchLoc = eventTouch.getLocation();
            const pos = this.convertTouchPosToPlane(touchLoc);
            if (pos) {
                this.isClick = true;
                this.node.on(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this);
            }
        }, this);

        this.node.on(cc.Node.EventType.TOUCH_CANCEL, function () {
            if(this.isClick) {
                this.isClick = false;
                // 最后一次监听
                cc.log('touch cancel');
                this.node.off(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this)
            }
        }, this);

        this.node.on(cc.Node.EventType.TOUCH_END, function () {
            if(this.isClick) {
                this.isClick = false;
                // 最后一次监听
                cc.log('touch end');
                this.node.off(cc.Node.EventType.TOUCH_MOVE, this.touchMove, this)
            }
        }, this);
    },

    // 移动时动作
    touchMove(eventTouch) {
        const res = this.controller.moving(eventTouch);
        // 移动
        this.updateView();
    },

    // 是否是飞机的坐标
    convertTouchPosToPlane(posLoc) {
        const pos = this.node.convertToNodeSpaceAR(posLoc);
        const isValid = this.plane.getBoundingBoxToWorld().contains(posLoc);
        if (!isValid) {
            return false;
        }
        // 当前点击飞机时，返回点击坐标
        if(pos.x < 0 || pos.x > g.SKY_WIDTH || pos.y < 0 || pos.y > g.SKY_HEIGHT) {
            return false;
        }
        return pos;
    },

    updateView() {
        this.planeViews[0].updateView();
        this.controller.cleanCmd();
    },

    /**
     * 更新碰撞效果
     * @param effectQueues，播放的动效
     * @param changeModels, 需要处理的敌机
     */
    updateCollision(changeModels, effectQueues) {
        // cc.log(`'update collision changeModels = ${JSON.stringify(changeModels)}, effectQueues = ${JSON.stringify(effectQueues)}`)
        // play effectQueues
        this.playEffects(effectQueues);
        for(const model of changeModels) {
            const id = model.id;
            if(!this.planeViews[id]) {
                // 防止死后，继续点击出错
                continue;
            }
            this.planeViews[id].updateView();
            if(id !== 0 && this.planeViews[id].model.isDead) {
                delete this.planeViews[id];
            }
            if (id === 0) {
                // 更新血量
                this.updateBlood(this.planeViews[0].model.attackTimes/3)
            }
        }
        this.controller.cleanCmd();
        if (this.planeViews[0].model.isDead) {
            this.gameOver = true;
            this.pauseGame();
        }
    },

    // 暂停动画
    pauseGame: function () {
        this.topBackground.node.pauseAllActions();
        this.downBackground.node.pauseAllActions();
        this.node.off(cc.Node.EventType.TOUCH_START);
        // 暂停敌机
        if (this.planeViews.length < 2) {
            return;
        }
        const enemies = Object.values(this.planeViews);
        for (const e of enemies) {
            if(!e.model) {
                // TODO 没有处理的敌机,自动销毁
                continue;
            }
            if (e.model.id !== 0) {
                e.node.pauseAllActions();
            }
        }
    },

    // 播放动效
    playEffects(effectQueues) {
        if(!effectQueues || effectQueues.length < 1) {
            return;
        }

        effectQueues.forEach(cmd => {
            const delayTime = cc.delayTime(cmd.playTime);
            let instantEffect = null;
            // 播放的动画
            let anim = null;
            if (cmd.action === g.EffectType.bomb) {
                const cb = cc.callFunc(function() {
                    instantEffect = cc.instantiate(this.bombPrefab);
                    anim = instantEffect.getComponent(cc.Animation);
                    anim.play('explode1');
                    instantEffect.x = cmd.x;
                    instantEffect.y = cmd.y;
                    this.node.addChild(instantEffect);
                    anim.on('finished', function () {
                        cc.log('destroy bomb');
                        instantEffect.destroy();
                    });
                }, this);
                this.node.runAction(cc.sequence(delayTime, cb))
            }
        }, this);
    },

    // 移动背景
    playMissionBackground: function () {
        cc.log('in play mission background');
        const topPos = cc.v2(0, g.SKY_HEIGHT);
        const downPos = cc.v2(0, 0);
        this.topBackground.node.setPosition(topPos);
        this.downBackground.node.setPosition(downPos);
        const bg = [this.downBackground.node, this.topBackground.node];
        for(let i = 0; i < bg.length; ++i ) {
            const node = bg[i];
            const dt = g.MOVE_BG_TIME*(i+1);
            const moveBack = cc.callFunc(function (target) {
                target.setPosition(topPos);
                // 不能写在外面，外面动效会失败
                // 采用move by不能适应手机
                const repeat = cc.moveTo(g.MOVE_BG_TIME*bg.length, cc.v2(0, g.SKY_HEIGHT*-1+10));
                target.runAction(cc.sequence(repeat, moveBack));
            }, node);
            const moveDown = cc.moveTo(dt, cc.v2(0, g.SKY_HEIGHT*-1+10));
            node.runAction(cc.sequence(moveDown, moveBack));
        }
    },

    updateBlood(value) {
        cc.log(`ste blood ${value}`);
        this.blood.fillRange = value;
    },
});
